package pl.edu.agh.iosr.gamblingzone.model;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne; 

import org.hibernate.annotations.CollectionOfElements;

/**
 * The Class AbstractEvent.
 * 
 */

@AttributeOverride(name="id",
		column=@Column(name="AEVENT_ID"))
@Entity(name="ABSTRACT_EVENTS")
@Inheritance(strategy = InheritanceType.JOINED)
public class AbstractEvent extends EntityModel {
	
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 8378003020104933128L;

	/** The closing date. */
	@Column(name="AEVENT_CLOSING_DATE", nullable=false)
	private Date closingDate;
	
	/** The creation date. */
	@Column(name="AEVENT_CREATION_DATE", nullable=false)
	private Date creationDate = new Date();
	
	/** The winner. */
	@OneToOne
	@JoinColumn(name="AEVENT_WINNER", nullable=true)
	private Participant winner = null;
	
	/** The rates. */
	@CollectionOfElements(fetch=FetchType.EAGER)
	private Map<Participant, Double> rates = new HashMap<Participant, Double>();
	
	/** The group. */
	@ManyToOne//(targetEntity=Group.class)
	@JoinColumn(name="GROUP_ID")
	private Group group;
	
	/**
	 * Gets the rates.
	 * 
	 * @return the rates
	 */
	public Map<Participant, Double> getRates() {
		return rates;
	}
	
	/**
	 * Adds the participant.
	 * 
	 * @param participant the participant
	 * @param rate the rate
	 */
	public void addParticipant(Participant participant, Double rate) {
		this.rates.put(participant, rate);
	}
	
	public void removeParticipant(Participant participant) {
		this.rates.remove(participant);
	}
	
	/**
	 * Sets the rates.
	 * 
	 * @param rates the rates
	 */
	public void setRates(Map<Participant, Double> rates) {
		this.rates = rates;
	}

	/**
	 * Gets the group.
	 * 
	 * @return the group
	 */
	public Group getGroup() {
		return group;
	}

	/**
	 * Sets the group.
	 * 
	 * @param group the new group
	 */
	protected void setGroup(Group group) {
		this.group = group;
	}

	/**
	 * Gets the winner.
	 * 
	 * @return the winner
	 */
	public Participant getWinner() {
		return winner;
	}

	/**
	 * Sets the winner.
	 * 
	 * @param winner the new winner
	 */
	public void setWinner(Participant winner) {
		this.winner = winner;
	}

	/**
	 * Gets the closing date.
	 * 
	 * @return the closing date
	 */
	public Date getClosingDate() {
		return closingDate;
	}

	/**
	 * Sets the closing date.
	 * 
	 * @param closingDate the new closing date
	 */
	public void setClosingDate(Date closingDate) {
		this.closingDate = closingDate;
	}

	/**
	 * Gets the creation date.
	 * 
	 * @return the creation date
	 */
	public Date getCreationDate() {
		return creationDate;
	}

	/**
	 * Sets the creation date.
	 * 
	 * @param creationDate the new creation date
	 */
	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}
	
	/* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
	// TODO
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof AbstractEvent)) return false;

        final AbstractEvent abstractEvent = (AbstractEvent) o;
        
        if ((getId() == null || getId() == 0L) || (abstractEvent.getId() == null || abstractEvent.getId() == 0L)) {
        	 if (!creationDate.equals(abstractEvent.creationDate)) return false;
        } else {
        	 if (!getId().equals(abstractEvent.getId()) ) return false;
        }
     
        return true;
    }
    
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    // TODO
    public int hashCode() {
    	int result = 17;

    	if (getId() == null || getId() == 0L) {
    		result = 37 * result + getCreationDate().hashCode();
    	} else {
    		result = getId().hashCode();
    	}
    	
    	return result;
    }
}
